package com.bigwolf.common.core.utils;

import com.bigwolf.common.core.exception.UtilException;
import com.bigwolf.common.core.utils.spring.SpringUtils;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.CollectionType;

import java.util.List;
import java.util.Map;

public class JsonUtils {
    private static final ObjectMapper objectMapper = SpringUtils.getBean(ObjectMapper.class);

    private JsonUtils() {}

    static {
        // 反序列化：JSON字段中有Java对象中没有的字段时不报错
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

        // 序列化：序列化BigDecimal时不使用科学计数法输出
        objectMapper.configure(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN, true);
    }

    public static <T> T toObject(String string, Class<T> cls) {
        try {
            return objectMapper.readValue(string, cls);
        } catch (JsonProcessingException e) {
            throw new UtilException(e);
        }
    }

    public static <T> T toObject(String str, CollectionType valueTypeRef) {
        try {
            return objectMapper.readValue(str, valueTypeRef);
        } catch (JsonProcessingException e) {
            throw new UtilException(e);
        }
    }

    public static <T> T toObject(Map<T, T> map, Class<T> cls) {
        return objectMapper.convertValue(map, cls);
    }

    @SuppressWarnings("rawtypes")
    public static Map toMap(String str) {
        try {
            return objectMapper.readValue(str, Map.class);
        } catch (JsonProcessingException e) {
            throw new UtilException(e);
        }
    }

    @SuppressWarnings("rawtypes")
    public static Map toMap(JsonNode node) {
        return objectMapper.convertValue(node, Map.class);
    }

    @SuppressWarnings("unchecked")
    public static Map<String, Object> toMap(Object obj) {

        return objectMapper.convertValue(obj, Map.class);
    }

    public static String toJson(Object obj) {
        try {
            return objectMapper.writeValueAsString(obj);
        } catch (JsonProcessingException e) {
            throw new UtilException(e);
        }
    }

    public static <T> List<T> toObjectList(String string, TypeReference<List<T>> typeReference) {
        try {
            return objectMapper.readValue(string, typeReference);
        } catch (Exception e) {
            throw new UtilException(e);
        }
    }

    public static JsonNode toTree(String string) {
        try {
            return objectMapper.readTree(string);
        } catch (JsonProcessingException e) {
            throw new UtilException(e);
        }
    }
}